#pragma once

#include <sys/epoll.h>
#include <errno.h>
#include "Log.hpp"
#include "Common.hpp"

using namespace LogModule;

class Epoller
{
public:
    Epoller() : _epfd(-1)
    {
        _epfd = epoll_create(128);
        if (_epfd < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_create error!";
            exit(EPOLL_CREATE_ERR);
        }
        LOG(LogLevel::INFO) << "epoll_create success! epfd= " << _epfd;
    }

    // 辅助CTLEventHleper函数
    void CTLEventHleper(int sockfd, int events, int op)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = events;
        int ret = epoll_ctl(_epfd, op, sockfd, &ev);
        if (ret < 0)
        {
            LOG(LogLevel::ERROR) << "epoll_ctl " << op << " error!";
            return;
        }
        LOG(LogLevel::INFO) << "epoll_ctl " << op << " success!  sockfd= " << sockfd;
    }

    // 添加事件
    void AddEvent(int sockfd, uint32_t events)
    {
        CTLEventHleper(sockfd, events, EPOLL_CTL_ADD);
    }

    // 删除事件
    void DelEvent(int sockfd)
    {
        CTLEventHleper(sockfd, 0, EPOLL_CTL_DEL);
    }

    // 修改事件
    void ModEvent(int sockfd, uint32_t events)
    {
        CTLEventHleper(sockfd, events, EPOLL_CTL_MOD);
    }

    // 等待事件
    int WaitEvents(struct epoll_event *revs, int maxnum, int timeout)
    {
        int n = epoll_wait(_epfd, revs, maxnum, timeout);
        if (n < 0)
        {
            // 出错
            LOG(LogLevel::WARNING) << "epoll_wait error!";
        }
        else if (n == 0)
        {
            // 超时
            LOG(LogLevel::WARNING) << "epoll_wait timeout!";
        }
        else
        {
        }
        return n;
    }

    ~Epoller()
    {
        if (_epfd >= 0)
        {
            close(_epfd);
        }
    }

private:
    int _epfd; // epoll文件描述符
};